home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Freeware 25 / FreelogHS25.iso / Dessin / ArtOfIllusion2.2.1 / Scripts / Tools / Join Objects.bsh next >
Text File  |  2005-06-11  |  14KB  |  454 lines

  1. /*
  2. <?xml version='1.0' standalone='yes' ?>
  3. <!--  xml header for scripts & plugin manager --> 
  4. <script>
  5.     <name>Join Objects</name>
  6.     <author>Julian MacDonald</author>
  7.     <version>1.8</version>
  8.     <beta>1</beta>
  9.     <date>04/20/2004</date>
  10.     <description>
  11. This script joins a set of selected objects into a single triangle mesh
  12. non-triangle meshes are converted to triangle meshes using the user-entered Max Error.
  13. Smoothness values for vertices and edges are retained.  There is also the ability to 'weld' vertices
  14. within a certain distance of each other.  
  15. Textures are also partly retained.
  16. Still to do:      support for layered textures
  17. Problems:    texture scaling/orientation/position not retained correctly (need access to methods - Peter to allow in next version)
  18.         if a texture is used more than once with different mappings, only the last mapping is transferred.
  19.     </description>
  20.     <comments>
  21.     </comments>
  22. </script>
  23. */
  24.  
  25.  
  26. scene=window.getScene();
  27. sel=scene.getSelection();
  28. //
  29. // make sure at least 2 objects have been selected
  30. if (sel.length<2) 
  31. {
  32.     new MessageDialog(window,"Select at least 2 objects");
  33.     return;
  34. }
  35. //
  36. ObjInfo=new ObjectInfo[sel.length];   // array for holding ObjInfos for each selected object
  37. //
  38. //
  39. //  get a name for the new object and tolerance for
  40. // triangle mesh conversion if required
  41. //
  42. nameField=new BTextField("JoinedMesh",20);
  43. tolField=new ValueField(0.02,ValueField.POSITIVE);
  44. yesWeld = new BCheckBox();
  45. weldTolField=new ValueField(0.01,ValueField.POSITIVE);
  46. yesTex=new BCheckBox();
  47. sp1=new Spacer(nameField,nameField);
  48. sp2=new Spacer(nameField,nameField);
  49. sp3=new Spacer(nameField,nameField);
  50. //
  51. widgets=new Widget[]{nameField,sp1,tolField,sp2,yesWeld,weldTolField,sp3,yesTex};
  52. labels=new String[]{"Name:",null,"Surface Accuracy:",null,"Weld Close Points:","Weld Distance:",null,"Retain Textures:"};
  53. dlg = new ComponentsDialog(window, "Options for Resulting Mesh:",widgets,labels);
  54. if (!dlg.clickedOk()) return;
  55. //
  56. objname = nameField.getText();
  57. tol=tolField.getValue();
  58. wantsWeld=yesWeld.getState();
  59. weldTol=weldTolField.getValue();
  60. wantsTex=yesTex.getState();
  61. //
  62. // go through selected objects and get ObjInfos
  63. // convert any non-triangle meshes to triangle meshes
  64. //
  65. count=0;
  66. for(int i=0;i<sel.length;i++)
  67. {
  68.     selObjInfo=scene.getObject(sel[i]);  // get the ith ObjInfo
  69.     if (selObjInfo.object instanceof TriangleMesh)   // if it's a triangle mesh get it
  70.     {
  71.         ObjInfo[i]=scene.getObject(sel[i]);
  72.     }  
  73.     else  // otherwise convert to a triangle mesh
  74.     {
  75.         Obj=selObjInfo.object.convertToTriangleMesh(tol);
  76.         ObjInfo[i]=new ObjectInfo(Obj,selObjInfo.coords,"");
  77.     }
  78. }
  79. //
  80. //
  81. // get number of vertices/faces in joined mesh
  82. vtot=0;
  83. ftot=0;
  84. etot=0;
  85. numV=new int[sel.length];
  86. for (i=0;i<sel.length;i++)
  87. {
  88.     v=ObjInfo[i].object.getVertices();
  89.     f=ObjInfo[i].object.getFaces();
  90.     e=ObjInfo[i].object.getEdges();
  91.     numV[i]=v.length;  // number of vertices in each object
  92.     vtot=vtot+v.length;   // total number of vertices in resulting mesh
  93.     ftot=ftot+f.length;  // total number of faces in resulting mesh
  94.     etot=etot+e.length;
  95. }
  96. //
  97. va=new Vec3[vtot];   // create an array to hold the new mesh vertex coordinates
  98. vs=new float[vtot];  // create an array to hold the new mesh vertex Smoothness values
  99. es=new float[etot];  // create an array to hold the new mesh edge Smoothness values
  100. fc=new int[ftot][3];  // create an array to hold the new mesh face data
  101. count=0;
  102. ecount=0;
  103. fcount=0;
  104. disp=0;
  105. // cycle through the selected objects
  106. for (i=0;i<sel.length;i++)
  107. {
  108.     // get vertex information and put into array for new mesh 
  109.     v=ObjInfo[i].object.getVertices();
  110.     mv=ObjInfo[i].coords.fromLocal();
  111.     for (j=0;j<v.length;j++)
  112.     {
  113.         newV=new Vec3(v[j].r);
  114.         mv.transform(newV);
  115.         va[count]=newV;
  116.         vs[count]=v[j].smoothness;
  117.         count++;
  118.     }
  119.     // get edge smoothness values and put into array for new mesh
  120.     e=ObjInfo[i].object.getEdges();
  121.     for (k=0;k<e.length;k++)
  122.     {
  123.         es[ecount]=e[k].smoothness;
  124.         ecount++;
  125.     }
  126.      // get face information and put into array for new mesh 
  127.     f=ObjInfo[i].object.getFaces();
  128.     for (j=0;j<f.length;j++)
  129.     {
  130.         fc[fcount][0]=f[j].v1+disp;
  131.         fc[fcount][1]=f[j].v2+disp;
  132.         fc[fcount][2]=f[j].v3+disp;
  133.         fcount++;
  134.     }
  135.     disp=disp+numV[i];
  136. }
  137. //
  138. //
  139. // add the new object to the scene
  140. newMesh=new TriangleMesh(va,fc);
  141. // put original smoothness values back
  142. newVerts=newMesh.getVertices();
  143. for (i=0;i<newVerts.length;i++)
  144. {
  145.     newVerts[i].smoothness=vs[i];
  146. }
  147. //
  148. newEdges=newMesh.getEdges();
  149. for (i=0;i<newEdges.length;i++)
  150. {
  151.     newEdges[i].smoothness=es[i];
  152. }
  153. //
  154. //
  155. //
  156. //   TEXTURES
  157. if (wantsTex)
  158. {
  159. // ** Transfer the texture information from the original objects to the new mesh **
  160. //
  161. layTex=new LayeredTexture();  // create a new LayeredTexture
  162. layMap=new LayeredMapping(layTex); // get the associated LayeredMapping
  163. //
  164. tex=new Texture[sel.length];  // array for textures of each object
  165. texMap=new TextureMapping[sel.length];  // array for texture mappings for each object texture
  166. //
  167. // loop through selected objects (and hence individual textures) and get the texture details
  168. fc=0;  // face count
  169. vc=0; // vertex count
  170. for (i=0;i<sel.length;i++)
  171. {
  172.     tex[i]=ObjInfo[i].object.getTexture();    // get the texture for the ith object
  173.     texMap[i]=ObjInfo[i].object.getTextureMapping().duplicate();  // get the mapping (i.e. type and scaling, orientation etc.)
  174.     layMap.addLayer(tex[i]);  // add the ith object's texture to the layered texture
  175.     layMap.setLayerMode(i,0);
  176. }
  177. newMesh.setTexture(layTex,layMap);   // apply the layered texture to the new mesh
  178. //
  179. //  The basic method here is to assign each layer of the new mesh's layered texture per-face
  180. //  and then map the appropriate texture layer to the part of the mesh corresponding to the original object
  181. //
  182. faceParVal=new FaceParameterValue[sel.length];
  183. for (h=0;h<sel.length;h++)
  184. {
  185.     // h is the texture number (i.e. h=0 is the texture of the first object, h=1 for second object etc.)
  186.     // i is the layer number
  187.     // texture numbers are ordered opposite to the layers they are in
  188.     //
  189.     texVal=new double[ftot];  // array to hold texture parameter values for each face
  190.     i=sel.length-1-h;   // layer number
  191.     texParams=new TextureParameter[texMap[h].getParameters().length];  // set up array for any texture parameters
  192. //    print(texMap[h].getParameters());
  193.     texParams=texMap[h].getParameters();  //get the texture parameters (if any) within the hth texture
  194.     //
  195.     tempParam=layMap.getLayerParameters(i);
  196.     faceParVal[i]=new FaceParameterValue(newMesh,tempParam[0]);
  197.     //  set the parameter values to 0 for the other parts of the mesh
  198.     for (f=0;f<fc;f++)
  199.     {
  200.         texVal[f]=0.0;
  201.     }
  202.     //  set the parameter values to 1 for the relevant faces
  203.     for (f=fc;f<fc+ObjInfo[h].object.getFaces().length;f++)
  204.     {
  205.         texVal[f]=1.0;
  206.     }
  207.     // set the parameter values to 0 for the other parts of the mesh
  208.     for (f=fc+ObjInfo[h].object.getFaces().length;f<ftot;f++)
  209.     {
  210.         texVal[f]=0.0;
  211.     }
  212.     newMesh.setParameterValue(tempParam[0],faceParVal[i]); 
  213.     faceParVal[i].setValue(texVal);
  214.     //
  215.     // correct the texture mapping centre
  216.     //
  217.     // for linear 3D mapping
  218.     if (texMap[i] instanceof LinearMapping3D)
  219.     {
  220.         texScale=texMap[i].getScale();
  221.         texCent=texMap[i].getCenter();
  222.         scaleCorr=new Vec3(1/texScale.x,1/texScale.y,1/texScale.z);
  223.         scaleCorr.multiply(ObjInfo[i].coords.getOrigin());
  224.         texMap[i].setCenter(scaleCorr);
  225.     }
  226.     // for 2D projection mapping
  227.     if (texMap[i] instanceof ProjectionMapping)
  228.     {
  229.         texScale=texMap[i].getScale();
  230.         texCent=texMap[i].getCenter();
  231.         scaleCorr1=new Vec2(1/texScale.x,1/texScale.y);
  232.         scaleCorr=new Vec2(scaleCorr1.x*ObjInfo[i].coords.getOrigin().x+texCent.x,scaleCorr1.y*ObjInfo[i].coords.getOrigin().y+texCent.y);
  233.         texMap[i].setCenter(scaleCorr);
  234.     }
  235.     // for cylindrical or spherical mapping
  236.     if ((texMap[i] instanceof CylindricalMapping)||(texMap[i] instanceof SphericalMapping))
  237.     {
  238.     //    paramVal=ObjInfo[i].object.getParameterValues();  //get texture coordinates
  239.     //    texCoordsX=paramVal[0].getValue();
  240.     //    texCoordsY=paramVal[1].getValue();
  241.     //    texCoordsZ=paramVal[2].getValue();
  242.     //    for (q=0;q<texCoordsX.length;q++)
  243.     //    {
  244.     //        texCoordsX[q]=texCoordsX[q]+ObjInfo[i].coords.getOrigin().x;
  245.     //        texCoordsY[q]=texCoordsY[q]+ObjInfo[i].coords.getOrigin().y;
  246.     //        texCoordsZ[q]=texCoordsZ[q]+ObjInfo[i].coords.getOrigin().z;
  247.     //    }
  248.     //    paramVal[0].setValue(texCoordsX);
  249.     //    paramVal[1].setValue(texCoordsY);
  250.     //    paramVal[2].setValue(texCoordsZ);
  251.         texMap[i].setBoundToSurface(true);
  252.     }
  253.     layMap.setLayerMapping(h,texMap[i]);  // set the mapping correctly
  254.     // cycle through the texture parameters, determine the mapping type and set the values for the
  255.     // relevant part of the new mesh
  256.     //
  257.     for (j=0;j<texParams.length;j++)
  258.     {
  259.         paramVal=ObjInfo[h].object.getParameterValue(texParams[j]);  // determine mapping type
  260.         //
  261.         //  *** per-object texture parameters ***
  262.         if (paramVal instanceof ConstantParameterValue)
  263.         {
  264.             tpVal=new double[ftot]; // array to hold texture parameter values for each face of new mesh
  265.             val=paramVal.getValue(); // single value containing value of the parameter for the original object
  266.             //  set the parameter values to 0 for the other parts of the mesh
  267.             for (f=0;f<fc;f++)
  268.             {
  269.                 tpVal[f]=0.0;
  270.             }
  271.             //  set the parameter values as per the original object for the relevant faces
  272.             for (f=fc;f<fc+ObjInfo[h].object.getFaces().length;f++)
  273.             {
  274.                 tpVal[f]=val;
  275.             }
  276.             // set the parameter values to 0 for the other parts of the mesh
  277.             for (f=fc+ObjInfo[h].object.getFaces().length;f<ftot;f++)
  278.             {
  279.                 tpVal[f]=0.0;
  280.             }
  281.             paramVal2=new FaceParameterValue(tpVal);  // make a new FaceParameterValue to apply to new mesh
  282.             newMesh.setParameterValue(texParams[j],paramVal2);  // apply it
  283.         }
  284.         //
  285.         //
  286.         // *** per-face texture parameters  ***
  287.         if (paramVal instanceof FaceParameterValue)
  288.         {
  289.             tpVal=new double[ftot];  // array to hold texture parameter values for each face of new mesh
  290.             valPerFace=paramVal.getValue();  // array containing values of the parameter for each face of original object
  291.             //  set the parameter values to 0 for the other parts of the mesh
  292.             for (f=0;f<fc;f++)
  293.             {
  294.                 tpVal[f]=0.0;
  295.             }
  296.             //  set the parameter values as per the original object for the relevant faces
  297.             for (f=fc;f<fc+ObjInfo[h].object.getFaces().length;f++)
  298.             {
  299.                 tpVal[f]=valPerFace[f-fc];
  300.             }
  301.             // set the parameter values to 0 for the other parts of the mesh
  302.             for (f=fc+ObjInfo[h].object.getFaces().length;f<ftot;f++)
  303.             {
  304.                 tpVal[f]=0.0;
  305.             }
  306.             paramVal2=new FaceParameterValue(tpVal);  // make a new FaceParameterValue to apply to new mesh
  307.             newMesh.setParameterValue(texParams[j],paramVal2);  // apply it
  308.         }
  309.         //
  310.         //
  311.         // *** per-vertex parameters ***
  312.         if (paramVal instanceof VertexParameterValue)
  313.         {
  314.             tpVal=new double[vtot]; // array to hold texture parameter values for each vertex of new mesh
  315.             valPerVert=paramVal.getValue(); // array containing values of the parameter for each vertex of original object
  316.             //  set the parameter values to 0 for the other parts of the mesh
  317.             for (v=0;v<vc;v++)
  318.             {
  319.                 tpVal[v]=0.0;
  320.             }
  321.             //  set the parameter values as per the original object for the relevant vertices
  322.             for (v=vc;v<vc+ObjInfo[h].object.getVertices().length;v++)
  323.             {
  324.                 tpVal[v]=valPerVert[v-vc];
  325.             }
  326.             //  set the parameter values to 0 for the other parts of the mesh
  327.             for (v=vc+ObjInfo[h].object.getVertices().length;v<vtot;v++)
  328.             {
  329.                 tpVal[v]=0.0;
  330.             }
  331.             paramVal2=new VertexParameterValue(tpVal); // make a new VertexParameterValue to apply to new mesh
  332.             newMesh.setParameterValue(texParams[j],paramVal2);  // apply it
  333.             print(paramVal2.getValue());
  334.         }
  335.         //
  336.         //
  337.         // *** per face-vertex texture parameters ***
  338.         if (paramVal instanceof FaceVertexParameterValue)
  339.         {
  340.             tpVal=new double[3][ftot]; // array to hold texture parameter values for each face-vertex of new mesh
  341.             valPerFace=paramVal.getValue(); //array containing values of the parameter for each face-vertex of original object
  342.             //  set the parameter values to 0 for the other parts of the mesh
  343.             for (f=0;f<fc;f++)
  344.             {
  345.                 tpVal[0][f]=0.0;
  346.                 tpVal[1][f]=0.0;
  347.                 tpVal[2][f]=0.0;
  348.             }
  349.             //  set the parameter values as per the original object for the relevant face-vertices
  350.             for (f=fc;f<fc+ObjInfo[h].object.getFaces().length;f++)
  351.             {
  352.                 tpVal[0][f]=valPerFace[0][f-fc];
  353.                 tpVal[1][f]=valPerFace[1][f-fc];
  354.                 tpVal[2][f]=valPerFace[2][f-fc];
  355.             }
  356.             // set the parameter values to 0 for the other parts of the mesh
  357.             for (f=fc+ObjInfo[h].object.getFaces().length;f<ftot;f++)
  358.             {
  359.                 tpVal[0][f]=0.0;
  360.                 tpVal[1][f]=0.0;
  361.                 tpVal[2][f]=0.0;
  362.             }
  363.             paramVal2=new FaceVertexParameterValue(tpVal);  // make a new FaceVertexParameterValue to apply to new mesh
  364.             newMesh.setParameterValue(texParams[j],paramVal2);  // apply it
  365.         }
  366.     }
  367.  
  368.     //
  369.     fc=fc+ObjInfo[h].object.getFaces().length;
  370.     vc=vc+ObjInfo[h].object.getVertices().length;
  371. }
  372. //
  373. //  add the new mesh to the scene.
  374. //
  375. newMesh.setTexture(layTex,layMap);   // apply the layered texture to the new mesh
  376. }
  377. //
  378. //
  379. //
  380. //  WELD
  381. //
  382. if (wantsWeld)
  383. {
  384.     vert=newVerts;
  385.     face=newMesh.getFaces();
  386.     edge=newEdges;
  387.     //
  388.     reassignV=new int[vert.length];
  389.     reposV=new int[vert.length];
  390.     numCoVert=0;
  391.     newVertIndex=new int [vert.length];
  392.     vToBeDel=new int[vert.length];
  393.     for (i=0;i<vert.length;i++)
  394.     {
  395.         reassignV[i]=-1;
  396.         reposV[i]=i;
  397.     }
  398.     //
  399.     for (v1=0;v1<vert.length;v1++)
  400.     {
  401.         for (v2=v1+1;v2<vert.length;v2++)
  402.         {
  403.             Dist=vert[v1].r.distance(vert[v2].r);
  404.             if ((Dist<weldTol)&&(reassignV[v2]==-1))
  405.             {
  406.                 reassignV[v2]=v1;
  407.                 for (k=v2+1;k<vert.length;k++)
  408.                 {
  409.                     reposV[k]--;
  410.                 }
  411.                 numCoVert++;
  412.             }
  413.         }
  414.     }
  415.     if (numCoVert==0)
  416.     {
  417.         new MessageDialog(window, "There are no vertices within the required tolerance");
  418.         return;
  419.     }
  420.     // build new index
  421.     for (i=0;i<vert.length;i++)
  422.     {
  423.         if (reassignV[i]!=-1) newVertIndex[i]=reposV[reassignV[i]]; else newVertIndex[i]=reposV[i];
  424.     }
  425.     //
  426.     // create new vertices skipping 'duplicates'
  427.     //
  428.     vCount=0;
  429.     newVert=new TriangleMesh.Vertex[vert.length-numCoVert];
  430.     for (i=0;i<vert.length;i++)   // cycle through the vertices
  431.     {
  432.         skip=0;
  433.         if (reassignV[i]==-1)
  434.         {
  435.             newVert[vCount]=vert[i];
  436.             vCount++;
  437.         }
  438.     } 
  439.     //
  440.     // reassign the face vertices
  441.     faceInfo=new int [face.length][3];
  442.     for (f=0;f<face.length;f++)
  443.     {
  444.         faceInfo[f][0]=newVertIndex[face[f].v1];
  445.         faceInfo[f][1]=newVertIndex[face[f].v2];
  446.         faceInfo[f][2]=newVertIndex[face[f].v3];
  447.     }
  448.     //
  449.     newMesh.setShape(newVert,faceInfo);
  450.     }
  451. //
  452. //
  453. window.addObject(newMesh,new CoordinateSystem(),objname,null);
  454.